home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / docs / linux-do / programm / lpg-0.4 / lpg-0 / LPG / examples / calc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-17  |  8.9 KB  |  307 lines

  1. /*
  2.  * CALC.C - A demonstration program for ncurses.
  3.  *          This program is originally distributed as a part of 
  4.  *          the <Linux Programmers Guide>
  5.  * 
  6.  *  AUTHOR: Sven van der Meer (vdmeer@cs.tu-berlin.de)
  7.  *
  8.  *  This program is free software; you can redistribute it and/or
  9.  *  modify it under the terms of the GNU General Public License as
  10.  *  published by the Free Software Foundation; either version 2 of
  11.  *  the License,or (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program; if not, write to the Free Software
  20.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. #include <ncurses/ncurses.h>
  25.  
  26.  
  27. /* My background window has 22 rows and 70 columns. These 
  28.  * two defines are logical coordinates to open the window
  29.  * in the middle of the screen, whatever dimension it has.
  30.  * TYPE_ROW is the beginning row for my program and TYPE_COL 
  31.  * the beginning column. Every call to newwin(...) will check
  32.  * these two defines.
  33.  */
  34. #define CALC_ROW (int) ((LINES-23)/2)
  35. #define CALC_COL (int) ((COLS-28)/2)
  36. #define ROW 5
  37. #define COL 3
  38. #define LEN 5
  39. #define HEI 3
  40.  
  41.  
  42. /*
  43.  * Global variables. I need three windows (one for the red box,
  44.  * one for the frame and one for the real output). Beg is for
  45.  * the output as offset in s[]. Scroll is an enum for calls to
  46.  * scroll_s (I hate to use integers for this).
  47.  * s[] is defined in type.h as:
  48.  * char *s[] = { <here is type.c> };
  49.  */
  50. WINDOW *screen_win;
  51. WINDOW *calc_win;
  52.  
  53.  
  54. /*
  55.  * Local function prototypes.
  56.  * init_type does the ncurses initializing
  57.  * end_type  does the exit for type
  58.  * vdmerase will erase a window with blanks (I had problems
  59.  *          with the ncurses erase functions, so I wrote my
  60.  *          function).
  61.  * scroll_s will do the scrolling (UP or DOWN).
  62.  * clear_line will send space characters from the current 
  63.  *            cursor position up to
  64.  *            the length from int.
  65.  * winsizech() is a signalhandler for SIGWINCH. this signal
  66.  *             will be caught when the screen size has changed
  67.  *             (resized xterm e.g.).
  68.  */
  69. void vdmerase(WINDOW *);
  70. void init_calc();
  71. void end_calc();
  72. void vdmbox(WINDOW *, int, int, int, int, int, int);
  73.  
  74.  
  75.  
  76. /*
  77.  * The main function.
  78.  */
  79. void main ()
  80. {
  81. bool okloop=TRUE;
  82.  
  83.  /* ncurses initializing */
  84.  init_calc();
  85.  
  86. /* ok, the screen has a white window with a box and a red
  87.  * border around it.
  88.  * Our main loop. Wait for pressed keys. When the user pressed
  89.  * 'q' or 'Q' then exit the program. On cursor down or 'd' or 'D'
  90.  * scroll the text in the window one line down, on cursor up or
  91.  * 'u' or 'U' one line up. On every other key do nothing.
  92.  */
  93.  while(okloop){
  94.    switch(getch()){
  95.      case 'q':
  96.      case 'Q': okloop=FALSE;
  97.      default : break;
  98.    }
  99.  }
  100.  /* clean uop end exit */
  101.  end_calc();
  102.  exit(0);
  103. }
  104.  
  105.  
  106.  
  107.  
  108. /*
  109.  *  init_type initialize the ncurses data structures, create the
  110.  *            needed windows, print them on screen and set some
  111.  *            usefull options.
  112.  *
  113.  */
  114. void init_calc()
  115. {
  116. int fg, bg;
  117.  
  118. /* don't forget this when using ncurses!!! */
  119.  if(!(stdscr=initscr())){
  120.    fprintf(stderr,"calc: initscr() failed\n\n");
  121.    exit (1);
  122.  }
  123.  
  124. /* check screen size. we need 20 lines and 18 columns */
  125.  if ((LINES<20)||(COLS<18)){
  126.    fprintf(stderr,"calc: screen to small\n\n");
  127.    endwin(); exit (1);
  128.  }
  129.  
  130. /* now we open our three windows */
  131.  if (!(screen_win=newwin(0,0,0,0))){
  132.    fprintf(stderr,"calc: can't open screen_win\n\n");
  133.    endwin(); exit (1);
  134.  }
  135.  
  136.  if (!(calc_win=newwin(22,26,CALC_ROW,CALC_COL))){
  137.    fprintf(stderr,"calc: can't open calc_win\n\n");
  138.    endwin(); exit (1);
  139.  }
  140.  
  141.  
  142. /* ok windows are opened, check for color */
  143.  start_color();
  144.  if (has_colors()){
  145.    /* fine we have colors, define color_pairs for foreground
  146.     * and background colors
  147.     */
  148.    init_pair(1,COLOR_BLACK,COLOR_BLUE);
  149.    init_pair(2,COLOR_BLACK,COLOR_WHITE);
  150.    init_pair(3,COLOR_WHITE,COLOR_WHITE);
  151.    /* now use the defined color_pairs for the windows */
  152.    wattrset(screen_win,COLOR_PAIR(1));
  153.    wattrset(calc_win,COLOR_PAIR(2));
  154.  }
  155.  else{
  156.    /* ohh, no color (maybe a vt100 or xterm). ok we use b&w
  157.     * attributes instead
  158.     */
  159.    wattrset(screen_win,A_REVERSE);
  160.    wattrset(calc_win,A_BOLD);
  161.  }
  162.  
  163. /* now clear the windows to get the attributes visible
  164.  * (in memory not on the screen).
  165.  */
  166.  vdmerase(screen_win);
  167.  vdmerase(calc_win);
  168.  
  169. /* wborder with spaces will only paint the border red */
  170.  wborder(screen_win,' ',' ',' ',' ',' ',' ',' ',' ');
  171.  
  172. /* and now the real box characters */
  173.  vdmbox(calc_win,COLOR_PAIR(3)|A_STANDOUT,COLOR_PAIR(2),
  174.         0,0,calc_win->_maxx,calc_win->_maxy);
  175.  
  176.  fg=COLOR_PAIR(2);
  177.  bg=COLOR_PAIR(3)|A_BOLD;
  178.  vdmbox(calc_win,fg,bg,COL,       ROW,       COL+LEN-1,   ROW+HEI-1);  /* Num */
  179.  vdmbox(calc_win,fg,bg,COL+LEN,   ROW,       COL+2*LEN-1, ROW+HEI-1);  /* /   */
  180.  vdmbox(calc_win,fg,bg,COL+2*LEN, ROW,       COL+3*LEN-1, ROW+HEI-1);  /* *   */
  181.  vdmbox(calc_win,fg,bg,COL+3*LEN, ROW,       COL+4*LEN-1, ROW+HEI-1);  /* -   */
  182.  vdmbox(calc_win,fg,bg,COL,       ROW+HEI,   COL+LEN-1,   ROW+2*HEI-1);/* 7   */
  183.  vdmbox(calc_win,fg,bg,COL+LEN,   ROW+HEI,   COL+2*LEN-1, ROW+2*HEI-1);/* 8   */
  184.  vdmbox(calc_win,fg,bg,COL+2*LEN, ROW+HEI,   COL+3*LEN-1, ROW+2*HEI-1);/* 9   */
  185.  vdmbox(calc_win,fg,bg,COL,       ROW+2*HEI, COL+LEN-1,   ROW+3*HEI-1);/* 4   */
  186.  vdmbox(calc_win,fg,bg,COL+LEN,   ROW+2*HEI, COL+2*LEN-1, ROW+3*HEI-1);/* 5   */
  187.  vdmbox(calc_win,fg,bg,COL+2*LEN, ROW+2*HEI, COL+3*LEN-1, ROW+3*HEI-1);/* 6   */
  188.  vdmbox(calc_win,fg,bg,COL,       ROW+3*HEI, COL+LEN-1,   ROW+4*HEI-1);/* 1   */
  189.  vdmbox(calc_win,fg,bg,COL+LEN,   ROW+3*HEI, COL+2*LEN-1, ROW+4*HEI-1);/* 2   */
  190.  vdmbox(calc_win,fg,bg,COL+2*LEN, ROW+3*HEI, COL+3*LEN-1, ROW+4*HEI-1);/* 3   */
  191.  vdmbox(calc_win,fg,bg,COL+3*LEN, ROW+HEI,   COL+4*LEN-1, ROW+3*HEI-1);/* +   */
  192.  vdmbox(calc_win,fg,bg,COL+3*LEN, ROW+3*HEI, COL+4*LEN-1, ROW+5*HEI-1);/* =   */
  193.  vdmbox(calc_win,fg,bg,COL,       ROW+4*HEI, COL+2*LEN-1, ROW+5*HEI-1);/* 0   */
  194.  vdmbox(calc_win,fg,bg,COL+2*LEN, ROW+4*HEI, COL+3*LEN-1, ROW+5*HEI-1);/* .   */
  195.  
  196.  mvwaddch(calc_win,ROW+1,       COL+LEN+2,   '/');
  197.  mvwaddch(calc_win,ROW+1,       COL+2*LEN+2, '*');
  198.  mvwaddch(calc_win,ROW+1,       COL+3*LEN+2, '-');
  199.  mvwaddch(calc_win,ROW+HEI+1,   COL+2,       '7');
  200.  mvwaddch(calc_win,ROW+HEI+1,   COL+LEN+2,   '8');
  201.  mvwaddch(calc_win,ROW+HEI+1,   COL+2*LEN+2, '9');
  202.  mvwaddch(calc_win,ROW+2*HEI+1, COL+2,       '4');
  203.  mvwaddch(calc_win,ROW+2*HEI+1, COL+LEN+2,   '5');
  204.  mvwaddch(calc_win,ROW+2*HEI+1, COL+2*LEN+2, '6');
  205.  mvwaddch(calc_win,ROW+3*HEI+1, COL+2,       '1');
  206.  mvwaddch(calc_win,ROW+3*HEI+1, COL+LEN+2,   '2');
  207.  mvwaddch(calc_win,ROW+3*HEI+1, COL+2*LEN+2, '3');
  208.  mvwaddch(calc_win,ROW+HEI+2,   COL+3*LEN+2, '+');
  209.  mvwaddch(calc_win,ROW+3*HEI+2, COL+3*LEN+2, '=');
  210.  mvwaddch(calc_win,ROW+4*HEI+1, COL+LEN,     '0');
  211.  mvwaddch(calc_win,ROW+4*HEI+1, COL+2*LEN+2, ',');
  212.  
  213.  vdmbox(calc_win,fg,bg,3,2,22,4);
  214.  wattrset(calc_win,COLOR_PAIR(2)|A_REVERSE);
  215.  mvwaddstr(calc_win,3,4,"012345678901234567");
  216.  wattrset(calc_win,COLOR_PAIR(2));
  217.  
  218. /* Now the terminal options.
  219.  * noecho the user typed characters, don't wait for input,
  220.  * make cursor invisible, don't wait for carriage return
  221.  * while waiting for input and enable the keypad
  222.  */
  223.  noecho();
  224.  nodelay(stdscr,FALSE);
  225.  cbreak();
  226.  curs_set(FALSE);
  227.  keypad(stdscr,TRUE);
  228.  
  229.  
  230. /* all window manipulations are done in the memory
  231.  * now we are going to get in on the physical screen.
  232.  * wnoutrefresh does everything in the memory, too, and
  233.  * doupdate will paint our screen!!!
  234.  */
  235.  wnoutrefresh(screen_win);
  236.  wnoutrefresh(calc_win);
  237.  doupdate();
  238. }
  239.  
  240.  
  241.  
  242. /* The user wants to terminate the program, ok clean up.
  243.  * Delete all opened windows and make the cursor visible.
  244.  * At least call endwin.
  245.  */
  246. void end_calc()
  247. {
  248.  delwin(screen_win);
  249.  delwin(calc_win);
  250.  curs_set(TRUE);
  251.  vdmerase(stdscr);
  252.  refresh();
  253.  endwin();
  254. }
  255.  
  256.  
  257.  
  258. /*
  259.  * With 'erase' and 'werase' from ncurses I don't get white
  260.  * spaces on black background (any idea why?), so I use 
  261.  * my own erase function.
  262.  * This goes deep in the structure WINDOW, so I don't recommend
  263.  * to use this function!!!
  264.  */
  265. void vdmerase (WINDOW *win)
  266. {
  267. int  y,x;
  268.  
  269.  for (y=0;y<=win->_maxy;y++)
  270.    for (x=0;x<=win->_maxx;x++)
  271.      (chtype *)win->_line[y][x]=' '|win->_attrs;
  272.  win->_curx = win->_cury = 0;
  273.  touchwin(win);
  274. return;
  275. }
  276.  
  277.  
  278.  
  279. void vdmbox(WINDOW *win, int fg, int bg, int begx, int begy, int maxx, int maxy)
  280. {
  281. int x,y;
  282.  
  283.  wattrset(win,fg);
  284.  mvwaddch(win,begy,begx,ACS_ULCORNER);
  285.  mvwaddch(win,maxy,begx,ACS_LLCORNER);
  286.  
  287.  wattrset(win,bg);
  288.  mvwaddch(win,begy,maxx,ACS_URCORNER);
  289.  mvwaddch(win,maxy,maxx,ACS_LRCORNER);
  290.  
  291.  for(x=begx+1;x<maxx;x++){
  292.    wattrset(win,fg);
  293.    mvwaddch(win,begy,x,ACS_HLINE);
  294.    wattrset(win,bg);
  295.    mvwaddch(win,maxy,x,ACS_HLINE);
  296.  }
  297.  
  298.  for(y=begy+1;y<maxy;y++){
  299.    wattrset(win,fg);
  300.    mvwaddch(win,y,begx,ACS_VLINE);
  301.    wattrset(win,bg);
  302.    mvwaddch(win,y,maxx,ACS_VLINE);
  303.  }
  304.  wattrset(win,fg);
  305. return;
  306. }
  307.